/*
    npm install -g typescript
    打开终端进入当前文件夹
    执行 tsc -v 查看是否有版本号
    执行 tsc --init 创建一个 ts 的配置文件
    找打 tsconfig.json 支持装饰器的语法配置，要解注释
    "experimentalDecorators": true, 
*/
/*
    什么是装饰器
    装饰器：
        就是一个方法(函数)，可以将函数内容注入到 类、方法、属性参数上，装饰器就是用来扩展
        类、属性、方法等功能用的。
    常见装饰器：
        普通装饰器，属性装饰器，方法装饰器，参数装饰器...
    装饰器写法：
        普通装饰器(没有参数)
        装饰器工厂(有参数)
*/


/*
function fn(target: any) {
    target.prototype.username = '老王'
}

// 使用装饰器，使用的时候 @装饰器函数的名称,不需要加括号调用
// 将函数注入到类中，person就可以用函数的内容，此时target是person的实例
@fn
class Person { }

const p1 = new Person()

// @ts-ignore 忽略编译错误用的
// @ts-ignore
console.log(p1.username);
*/



/*
// 装饰器工厂
function fn(option: { name: string, age: number }) {

    // 装饰器函数
    return (target: any) => {
        target.prototype.username = option.name
        target.prototype.age = option.age
    }
}

@fn({
    name: '张三',
    age: 18
})
class Person { }
const p1 = new Person()
// @ts-ignore
console.log(p1.age, p1.username);

*/


// ---------------------------------------
function f1(target: any) {
    console.log('f1');
}

function f2(option: any) {
    console.log('f2外部');
    return (target: any) => {
        console.log('f2内部');
    }
}

function f3(target: any) {
    console.log('f3');
}

function f4(option: any) {
    console.log('f4外部');
    return (target: any) => {
        console.log('f4内部');
    }
}

// 会先从上向下执行所有的装饰器工厂，然后拿到真正的装饰器，然后从下往上执行所有的装饰器
// ？ 执行顺序是什么 f2外，f4外，f4内，f3,f2内，f1
@f1
@f2({})
@f3
@f4({})
class Person { }
